òɾۿûѧϰʹá
ԭַhttps://www.joinquant.com/post/13673

ԭһ˵ʽ鵽ԭĺ߽ۡ


ԭĲԴ£

# 뺯
import jqdata
import datetime
import pandas as pd
import numpy as np

# ʼ趨׼ȵ
def initialize(context):
    # 趨300Ϊ׼
    set_benchmark('000300.XSHG')
    # ̬Ȩģʽ(ʵ۸)
    set_option('use_real_price', True)
    # ƱÿʽʱǣʱӶ֮ʱӶ֮ǧ֮һӡ˰, ÿʽӶͿ5Ǯ
    set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003, min_commission=5), type='stock')
    # ʱ
    run_daily(before_open, time='08:00', reference_security='000300.XSHG')
    run_daily(market_open, time='open', reference_security='000300.XSHG')
    set_params(context)

# ȫֱ
def set_params(context):
    g.stock_list = ['601238.XSHG']  # Ʊ
    g.maxnum = 1  # ֲ
    g.lower = -2  # 
    g.upper = 1  # 
    
    g.zscore_window = 60  # zscore
    g.ma_window = 20  # ߴ
    log.set_level('order', 'error')

# ȡƱ
def get_buy_sell(context):
    #stock_list = get_index_stocks('000016.XSHG')[:10]
    yesterday = context.current_dt - datetime.timedelta(1)  # 
    count = g.zscore_window + g.ma_window - 1  # 2
    price_df = get_price(g.stock_list, end_date=yesterday, fields='close', count=count).close
    data = get_current_data()  # ǰʱ
    buy, sell = [], []
    for code in g.stock_list:
        if data[code].paused:  # ͣƹ
            continue
        single_df = price_df[code].to_frame('close')
        single_df['ma'] = pd.rolling_mean(single_df.close, window=g.ma_window)  # 
        single_df.dropna(inplace=True)
        single_df['sub'] = single_df.close - single_df.ma  # Բֵлع
        zscore_mean = single_df['sub'].mean(); zscore_std = single_df['sub'].std()  # ֵͱ׼
        zscore_value = (single_df['sub'][-1] - zscore_mean) / zscore_std  # zscoreֵ
        record(zscore=zscore_value)
        record(lower=g.lower)
        record(upper=g.upper)
        hold = context.portfolio.positions.keys()
        if zscore_value <= g.lower and code not in hold:  # 
            buy.append(code)
        if zscore_value >= g.upper and code in hold:  # 
            sell.append(code)
    return buy, sell

## ǰк
def before_open(context):
    g.buy, g.sell = get_buy_sell(context)
    
## ʱк
def market_open(context):
    # 
    for code in g.sell:
        order_target(code, 0)
    # 
    for code in g.buy:
        hold = len(context.portfolio.positions)
        # δﵽֲ
        if hold < g.maxnum:
            cash_per_stock = context.portfolio.available_cash / (g.maxnum - hold)  # ʽ
            order_target_value(code, cash_per_stock)
    print('buy: %d  sell: %d  hold: %d' % (len(g.buy), len(g.sell), len(context.portfolio.positions)))
